package session

import (
	"sync"
	"time"
	"net/url"
	"net/http"
)

type Provider interface {
	Get(w http.ResponseWriter, r *http.Request) (string, error)
	Set(w http.ResponseWriter, r *http.Request, key string) error
	Del(w http.ResponseWriter, r *http.Request) error
}

type cookie struct {
	Name    string
	mute    sync.Mutex
	cookie	*http.Cookie
	expire  time.Duration
}

func NewCookie(name, domain, path string, secure bool, expire time.Duration) *cookie {
	return &cookie{
		Name:   name,
		expire: expire,
		cookie: &http.Cookie{
			Name:     name,
			Path:     path,
			Domain:   domain,
			Secure:   secure,
			HttpOnly: true,
		},
	}
}

func (c *cookie) Get(w http.ResponseWriter, r *http.Request) (string, error) {
	cookie, _ := r.Cookie(c.Name)

	if cookie == nil || len(cookie.Value) <= 0 {
		return "", nil
	}

	sessionId, _ := url.QueryUnescape(cookie.Value)

	return sessionId, nil
}

func (c *cookie) Set(w http.ResponseWriter, r *http.Request, value string) error {
	expires := c.expire
	if expires < time.Minute {
		expires = time.Minute
	}

	c.mute.Lock()
	c.cookie.Value   = value
	c.cookie.MaxAge  = int(c.expire.Seconds())
	c.cookie.Expires = time.Now().Add(expires)
	http.SetCookie(w, c.cookie)
	c.mute.Unlock()

	return nil
}

func (c *cookie) Del(w http.ResponseWriter, r *http.Request) error {
	c.mute.Lock()
	c.cookie.MaxAge = -1
	c.mute.Unlock()
	http.SetCookie(w, c.cookie)

	return nil
}